class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}
export default class DoublyLinkList {
    constructor() {
        this.head = null;
        this.length = 0;
        this.tail = null;
    }

    append(data) {
        let newnode = new Node(data);
        if (this.length === 0) {
            this.head = newnode;
            this.tail = newnode;
        } else {
            newnode.prev = this.tail;
            this.tail.next = newnode;
            this.tail = newnode;
        }
        this.length += 1;
    }

    backwardString() {
        let current = this.head;
        let result = '';
        while (current) {
            result += current.data + ' ';
            current = current.next;
        }
        return result;
    }

    forwardString() {
        let current = this.tail;
        let result = '';
        while (current) {
            result += current.data + ' ';
            current = current.prev;
        }
        return result;
    }

    toString() {
        return this.backwardString();
    }

    insert(position, data) {
        if (position < 0 || position > this.length) return false
        let newnode = new Node(data);
        if (this.length === 0) {
            this.head = newnode;
            this.tail = newnode;
        } else if (position === this.length) {
            newnode.prev = this.tail
            this.tail.next = newnode;
            this.tail = newnode;
        } else {
            let index = 0;
            let current = this.head;
            while (index++ < position) {
                current = current.next;
            }
            newnode.next = current;
            newnode.next = current.prev
            current.prev.next = newnode
            current.prev = newnode
        }
        this.length += 1
        return true
    }

    get(position) {
        if (position < 0 || position >= this.length) return null
        if (position < this.length / 2) {
            let current = this.head
            let index = 0
            while (index++ < position) {
                current = current.next
            }
            return current.data
        } else {
            let current = this.tail
            let index = this.length
            while (index-- > position) {
                current = current.prev
            }
            return current.data
        }

    }

    indexOf(data) {
        let current = this.head
        let index = 0
        while (current) {
            if (current.data === data) {
                return index
            }
            current = current.next
            index += 1
        }
        return -1
    }

    updata(position, newdata) {
        if (position < 0 || position >= this.length) return false
        if (position < this.length / 2) {
            let current = this.head
            let index = 0
            while (index++ < position) {
                current = current.next
            }
            current.data = newdata
            return true
        } else{
            let current = this.tail
            let index = this.length
            while (index-- >  position) {
                current = current.prev
            }
            current.data = newdata
            return true
        }

    }

    removeAt(position) {
        if (position < 0 || position >= this.length) return null
        let current = this.head
        if (this.length === 1) {
            this.head =null
            this.tail =null
        } else {
            if(position === 0){
                this.head.next.prev =null;
                this.head = this.head.next
            } else if(position === this.length-1){
                current =this.tail
                this.tail.prev.next = null
                this.tail = this.tail.prev
            }else{
                let index = 0
                while (index++ < position) {
                    current = current.next
                }
                current.prev.next = current.next
                current.next.prev = current.prev
            }
            
        }
        this.length-=1
        return current
    }

    remove(data){
        return this.removeAt(this.indexOf(data))
    }

    isEmpty() {
        return this.length === 0;
    }

    size() {
        return this.length
    }

    getHead(){
        return this.head.data
    }

    getTail(){
        return this.tail.data
    }
    
}